package com.dlx.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dlx.acl.client.UserFeignClient;
import com.dlx.activity.client.RechargeActivityFeignClient;
import com.dlx.common.exception.SmmsException;
import com.dlx.common.result.Result;
import com.dlx.mem.client.MemInfoFeignClient;
import com.dlx.mem.client.MemLevelFeignClient;
import com.dlx.model.acl.User;
import com.dlx.model.mem.MemInfo;
import com.dlx.model.mem.MemLevel;
import com.dlx.model.order.ConsumeOrderInfo;
import com.dlx.order.mapper.ConsumerOrderInfoMapper;
import com.dlx.order.service.ConsumeOrderInfoService;
import com.dlx.vo.order.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author nglon
 * @since 2021-11-16
 */
@Service
public class ConsumeOrderInfoServiceImpl extends ServiceImpl<ConsumerOrderInfoMapper, ConsumeOrderInfo> implements ConsumeOrderInfoService {

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private MemInfoFeignClient memInfoFeignClient;

    @Autowired
    private MemLevelFeignClient memLevelFeignClient;

    @Autowired
    private RechargeActivityFeignClient rechargeActivityFeignClient;

    @Override
    public Boolean consume(ConsumeVo consumeVo) {
        User user = this.userFeignClient.getCurrentUser();
        if (!user.getPassword().equals(consumeVo.getPaymentPassword())) {
            throw new SmmsException(332, "账号密码错误");
        }
        MemInfo memInfo = memInfoFeignClient.getByUserId(user.getId());
        MemLevel memLevel = memLevelFeignClient.getById(memInfo.getLevelId());
        BigDecimal actualAmount = consumeVo.getConsumeAmount().multiply(memLevel.getDiscount());
        if(memInfo.getBalance().compareTo(actualAmount)<0){
            throw new SmmsException(201,"当前账户余额不足,请先充值再消费");
        }
        memInfo.setBalance(actualAmount);

        boolean flag = false;
        ConsumeOrderInfo consumeOrderInfo = new ConsumeOrderInfo();
        consumeOrderInfo.setMemInfoId(memInfo.getId());
        consumeOrderInfo.setRemark(consumeVo.getRemark());
        consumeOrderInfo.setAmountReceivable(consumeVo.getConsumeAmount());
        consumeOrderInfo.setActualAmount(actualAmount);

        Result memInfoResult = memInfoFeignClient.update(memInfo);
        flag = baseMapper.insert(consumeOrderInfo) > 0;
        return flag&&memInfoResult.getCode()==200;
    }

    @Override
    public Page<ConsumeOrderInfo> selectConsumeOrderInfoPage(Long current, Long limit, ConsumeOrderInfoQueryVo consumeOrderInfoQueryVo) {
        User user = this.userFeignClient.getCurrentUser();
        MemInfo memInfo = this.memInfoFeignClient.getByUserId(user.getId());
        QueryWrapper<ConsumeOrderInfo> wrapper = new QueryWrapper<>();
        if (!"admin".equals(user.getUsername())) {
            wrapper.eq("mem_info_id",memInfo.getId());
        }
        if(consumeOrderInfoQueryVo.getId()!=null){
            wrapper.like("id",consumeOrderInfoQueryVo.getId());
        }
        if(consumeOrderInfoQueryVo.getMinAmount()!=null){
            wrapper.ge("actual_amount",consumeOrderInfoQueryVo.getMinAmount());
        }
        if(consumeOrderInfoQueryVo.getMaxAmount()!=null){
            wrapper.le("actual_amount",consumeOrderInfoQueryVo.getMaxAmount());
        }

        Page<ConsumeOrderInfo> consumeOrderInfoPage = this.baseMapper.selectPage(new Page<>(current, limit), wrapper);
        consumeOrderInfoPage.getRecords().forEach(this::packageConsumeOrderInfo);
        return consumeOrderInfoPage;
    }

    @Override
    public ConsumeOrderInfo show(Long id) {
        ConsumeOrderInfo consumeOrderInfo = this.baseMapper.selectById(id);
        this.packageConsumeOrderInfo(consumeOrderInfo);
        return consumeOrderInfo;
    }

    @Override
    public Map<String, Object> getMonthlyReport(ConsumeOrderReportQueryVo vo) {
        Map<String, Object> map = new HashMap<>();
        List<ConsumeOrderReportVo> consumeOrderReportVoList = this.baseMapper.selectMonthlyReport(vo);
        List<String> xCoordinatesList = consumeOrderReportVoList.stream().map(ConsumeOrderReportVo::getXCoordinates).collect(Collectors.toList());
        List<BigDecimal> yCoordinatesList = consumeOrderReportVoList.stream().map(ConsumeOrderReportVo::getYCoordinates).collect(Collectors.toList());
        map.put("xCoordinatesList",xCoordinatesList);
        map.put("yCoordinatesList",yCoordinatesList);
        return map;
    }

    @Override
    public Map<String, Object> getQuarterlyReport(ConsumeOrderReportQueryVo vo) {
        Map<String, Object> map = new HashMap<>();
        List<ConsumeOrderReportVo> consumeOrderReportVoList = this.baseMapper.selectQuarterlyReport(vo);
        List<String> xCoordinatesList = consumeOrderReportVoList.stream().map(ConsumeOrderReportVo::getXCoordinates).collect(Collectors.toList());
        List<BigDecimal> yCoordinatesList = consumeOrderReportVoList.stream().map(ConsumeOrderReportVo::getYCoordinates).collect(Collectors.toList());
        map.put("xCoordinatesList",xCoordinatesList);
        map.put("yCoordinatesList",yCoordinatesList);
        return map;
    }

    @Override
    public Map<String, Object> getAnnualReport() {
        Map<String, Object> map = new HashMap<>();
        List<ConsumeOrderReportVo> consumeOrderReportVoList = this.baseMapper.selectAnnualReport();
        List<String> xCoordinatesList = consumeOrderReportVoList.stream().map(ConsumeOrderReportVo::getXCoordinates).collect(Collectors.toList());
        List<BigDecimal> yCoordinatesList = consumeOrderReportVoList.stream().map(ConsumeOrderReportVo::getYCoordinates).collect(Collectors.toList());
        map.put("xCoordinatesList",xCoordinatesList);
        map.put("yCoordinatesList",yCoordinatesList);
        return map;
    }

    @Override
    public MemLevel getDiscount() {
        User user = this.userFeignClient.getCurrentUser();
        MemInfo memInfo = this.memInfoFeignClient.getByUserId(user.getId());
        MemLevel memLevel = this.memLevelFeignClient.getById(memInfo.getLevelId());
        return memLevel;
    }

    private void packageConsumeOrderInfo(ConsumeOrderInfo consumeOrderInfo) {
        consumeOrderInfo.getParam().put("consumerUsername",this.userFeignClient.getCurrentUser().getNickName());
    }
}
